﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.Revit;
using HYDrawTool;
using YJKRGeometry;
using HYView;

namespace YJKArch.NumberRoom
{
	internal class RoomNameSelReplaceManager
	{
		public RoomNameSelReplaceManager(ExternalCommandData commandData)
		{
			this.m_uiDoc = commandData.Application.ActiveUIDocument;
			this.m_doc = this.m_uiDoc.Document;
			this.CreatePosLineStyle();
		}

		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public Result ModifyRoomTag()
		{
			RoomNameSearchReplaceForm roomNameSearchReplaceForm = new RoomNameSearchReplaceForm();
			roomNameSearchReplaceForm.Show(CmdRoomNameSearchReplace._hWndRevit);
			int wMsg = 7;
			RoomNameSelReplaceManager.SendMessage(CmdRoomNameSearchReplace._hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
            Result result = Result.Cancelled;
			try
			{
				do
				{
					switch (roomNameSearchReplaceForm.SeletType)
					{
					case RoomNameSearchReplaceForm.SelecionType.eBoxSel:
						result = this.BoxSelectOperationRoomTag(roomNameSearchReplaceForm);
						break;
					case RoomNameSearchReplaceForm.SelecionType.eCurView:
					case RoomNameSearchReplaceForm.SelecionType.eAllView:
						result = this.ModifyViewRoomTag();
						break;
					case RoomNameSearchReplaceForm.SelecionType.ePickSearch:
					case RoomNameSearchReplaceForm.SelecionType.ePickReplace:
						result = this.PickSearchReplaceText(roomNameSearchReplaceForm);
						break;
					}
				}
				while (result == Autodesk.Revit.UI.Result.Cancelled || (result == Autodesk.Revit.UI.Result.Failed && roomNameSearchReplaceForm.OperChange));
			}
			catch (Exception)
			{
				roomNameSearchReplaceForm.Close();
				return Autodesk.Revit.UI.Result.Failed;
			}
			roomNameSearchReplaceForm.Close();
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private Result BoxSelectOperationRoomTag(RoomNameSearchReplaceForm dlg)
		{
			this.m_lstRoomTag.Clear();
			FilterRoomTag filterRoomTag = new FilterRoomTag();
			try
			{
				IList<Element> lstRoomTags = this.m_uiDoc.Selection.PickElementsByRectangle(filterRoomTag, "请框选房间标记");
				RoomNameSearchReplaceForm.RoomTagOperation roomTagOper = dlg.RoomTagOper;
				if (roomTagOper != RoomNameSearchReplaceForm.RoomTagOperation.eReplace)
				{
					if (roomTagOper == RoomNameSearchReplaceForm.RoomTagOperation.ePreSuffix)
					{
						int num = this.PreSuffixBoxSelRoomTag(lstRoomTags, dlg.SearchText, dlg.PrefixText, dlg.SuffixText);
						if (num == 0)
						{
							YJKMessageBox.Show("未找到要添加前后缀的房间名称");
						}
						else
						{
							YJKMessageBox.Show("共添加：" + num.ToString() + "个房间名称的前后缀");
						}
					}
				}
				else
				{
					int num2 = this.ReplaceBoxSelRoomTag(lstRoomTags, dlg.SearchText, dlg.ReplaceText);
					if (num2 == 0)
					{
						YJKMessageBox.Show("未找到要替换的房间名称");
					}
					else
					{
						YJKMessageBox.Show("共替换：" + num2.ToString() + "个房间名称");
					}
				}
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		private int ReplaceBoxSelRoomTag(IList<Element> lstRoomTags, string strSearch, string strReplace)
		{
			this.m_lstRoomTag.Clear();
			foreach (Element element in lstRoomTags)
			{
				RoomTag roomTag = element as RoomTag;
				if (roomTag != null && roomTag.Room.get_Parameter(BuiltInParameter.ROOM_NAME).AsString().ToLower().Contains(strSearch.ToLower()))
				{
					this.m_lstRoomTag.Add(roomTag);
				}
			}
			int num = 0;
			if (this.m_lstRoomTag.Count <= 0)
			{
				return num;
			}
			Transaction transaction = new Transaction(this.m_doc, "Replace Room Name");
			try
			{
				transaction.Start();
				foreach (RoomTag roomTag2 in this.m_lstRoomTag)
				{
					if (roomTag2 != null)
					{
						Room room = roomTag2.Room;
						if (room != null)
						{
							Parameter parameter = room.GetParameter(BuiltInParameter.ROOM_NAME);
							string text = parameter.AsString();
							text = text.Replace(strSearch, strReplace);
							parameter.Set(text);
							num++;
						}
					}
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
			return num;
		}

		private int PreSuffixBoxSelRoomTag(IList<Element> lstRoomTags, string strSearch, string strPrefix, string strSuffix)
		{
			this.m_lstRoomTag.Clear();
			foreach (Element element in lstRoomTags)
			{
				RoomTag roomTag = element as RoomTag;
				if (roomTag != null && roomTag.Room.get_Parameter(BuiltInParameter.ROOM_NAME).AsString().ToLower().Contains(strSearch.ToLower()))
				{
					this.m_lstRoomTag.Add(roomTag);
				}
			}
			int num = 0;
			if (this.m_lstRoomTag.Count <= 0)
			{
				return num;
			}
			Transaction transaction = new Transaction(this.m_doc, "PreSuffix Room Name");
			try
			{
				transaction.Start();
				foreach (RoomTag roomTag2 in this.m_lstRoomTag)
				{
					if (roomTag2 != null)
					{
						Room room = roomTag2.Room;
						if (room != null)
						{
							Parameter parameter = room.GetParameter(BuiltInParameter.ROOM_NAME);
							string text = parameter.AsString();
							int num2 = text.IndexOf(strSearch);
							string text2 = text.Substring(0, num2);
							string text3 = text.Substring(num2 + strSearch.Length);
							text = string.Concat(new string[]
							{
								text2,
								strPrefix,
								strSearch,
								strSuffix,
								text3
							});
							parameter.Set(text);
							num++;
						}
					}
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
			return num;
		}

		private Result ModifyViewRoomTag()
		{
			try
			{
				this.m_uiDoc.Selection.PickElementsByRectangle("");
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		public bool CheckInCurView(string strSearch)
		{
			this.m_lstRoomTag.Clear();
			this.CollectTextRoomTag(strSearch, true);
			if (this.m_lstRoomTag.Count <= 0)
			{
				YJKMessageBox.Show("没有可以查看的内容");
				return false;
			}
			this.PositionTextRoomTag();
			return true;
		}

		public Result ModifyRoomTagName(RoomNameSearchReplaceForm dlg)
		{
			try
			{
				RoomNameSearchReplaceForm.RoomTagOperation roomTagOper = dlg.RoomTagOper;
				if (roomTagOper != RoomNameSearchReplaceForm.RoomTagOperation.eReplace)
				{
					if (roomTagOper == RoomNameSearchReplaceForm.RoomTagOperation.ePreSuffix)
					{
						int num;
						if (dlg.SeletType == RoomNameSearchReplaceForm.SelecionType.eCurView)
						{
							num = this.PreSuffixRoomTag(dlg.SearchText, dlg.PrefixText, dlg.SuffixText, true);
						}
						else
						{
							num = this.PreSuffixRoomTag(dlg.SearchText, dlg.PrefixText, dlg.SuffixText, false);
						}
						if (num == 0)
						{
							YJKMessageBox.Show("未找到要添加前后缀的房间名称");
						}
						else
						{
							YJKMessageBox.Show("共添加：" + num.ToString() + "个房间名称的前后缀");
						}
					}
				}
				else
				{
					int num2;
					if (dlg.SeletType == RoomNameSearchReplaceForm.SelecionType.eCurView)
					{
						num2 = this.ReplaceRoomTag(dlg.SearchText, dlg.ReplaceText, true);
					}
					else
					{
						num2 = this.ReplaceRoomTag(dlg.SearchText, dlg.ReplaceText, false);
					}
					if (num2 == 0)
					{
						YJKMessageBox.Show("未找到要替换的房间名称");
					}
					else
					{
						YJKMessageBox.Show("共替换：" + num2.ToString() + "个房间名称");
					}
				}
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private void CollectTextRoomTag(string strText, bool bCurView)
		{
			this.CollectCurrentProjectRoomTag(strText, bCurView);
		}

		private void CollectCurrentProjectRoomTag(string strText, bool bCurView)
		{
			FilteredElementCollector filteredElementCollector;
			if (bCurView)
			{
				filteredElementCollector = new FilteredElementCollector(this.m_doc, this.m_doc.ActiveView.Id).OfClass(typeof(SpatialElementTag));
			}
			else
			{
				filteredElementCollector = new FilteredElementCollector(this.m_doc).OfClass(typeof(SpatialElementTag));
			}
			foreach (Element element in filteredElementCollector)
			{
				RoomTag roomTag = element as RoomTag;
				if (roomTag != null)
				{
					Room room = roomTag.Room;
					if (room != null && room.get_Parameter(BuiltInParameter.ROOM_NAME).AsString().ToLower().Contains(strText.ToLower()))
					{
						this.m_lstRoomTag.Add(roomTag);
					}
				}
			}
		}

		private void CollectLinkProjectRoomTag(string strText, bool bCurView)
		{
			IEnumerable<Document> linkDocuments = this.m_doc.GetLinkDocuments();
			if (linkDocuments == null || linkDocuments.Count<Document>() <= 0)
			{
				return;
			}
			foreach (Autodesk.Revit.DB.Document document in linkDocuments)
			{
				if (document != null)
				{
					FilteredElementCollector filteredElementCollector;
					if (bCurView)
					{
						Autodesk.Revit.DB.View curViewFromLinkDoc = this.GetCurViewFromLinkDoc(document);
						if (curViewFromLinkDoc == null)
						{
							continue;
						}
						filteredElementCollector = new FilteredElementCollector(document, curViewFromLinkDoc.Id).OfClass(typeof(SpatialElementTag));
					}
					else
					{
						filteredElementCollector = new FilteredElementCollector(document).OfClass(typeof(SpatialElementTag));
					}
					foreach (Element element in filteredElementCollector)
					{
						RoomTag roomTag = element as RoomTag;
						if (roomTag != null)
						{
							Room room = roomTag.Room;
							if (room != null && room.get_Parameter(BuiltInParameter.ROOM_NAME).AsString().ToLower().Contains(strText.ToLower()))
							{
								this.m_lstRoomTag.Add(roomTag);
							}
						}
					}
				}
			}
		}

		private Autodesk.Revit.DB.View GetCurViewFromLinkDoc(Autodesk.Revit.DB.Document docLink)
		{
			foreach (Autodesk.Revit.DB.ViewPlan viewPlan in FloorSelectManager.GetAllFloorViewPlan(docLink))
			{
				if (Geometry.IsEqual(viewPlan.GenLevel.Elevation, this.m_doc.ActiveView.GenLevel.Elevation))
				{
					return viewPlan;
				}
			}
			return null;
		}

		private int ReplaceRoomTag(string strSearch, string strReplace, bool bCurView)
		{
			int num = 0;
			this.m_lstRoomTag.Clear();
			this.CollectTextRoomTag(strSearch, bCurView);
			if (this.m_lstRoomTag.Count <= 0)
			{
				return num;
			}
			Transaction transaction = new Transaction(this.m_doc, "Replace Room Name");
			try
			{
				transaction.Start();
				foreach (RoomTag roomTag in this.m_lstRoomTag)
				{
					if (roomTag != null)
					{
						Room room = roomTag.Room;
						if (room != null)
						{
							Parameter parameter = room.GetParameter(BuiltInParameter.ROOM_NAME);
							string text = parameter.AsString();
							text = text.Replace(strSearch, strReplace);
							parameter.Set(text);
							num++;
						}
					}
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				num = 0;
				transaction.RollBack();
			}
			this.ClearPosRectangle(false);
			return num;
		}

		private int PreSuffixRoomTag(string strSearch, string strPrefix, string strSuffix, bool bCurView)
		{
			int num = 0;
			this.m_lstRoomTag.Clear();
			this.CollectTextRoomTag(strSearch, bCurView);
			if (this.m_lstRoomTag.Count <= 0)
			{
				return num;
			}
			Transaction transaction = new Transaction(this.m_doc, "PreSuffix Room Name");
			try
			{
				transaction.Start();
				foreach (RoomTag roomTag in this.m_lstRoomTag)
				{
					if (roomTag != null)
					{
						Room room = roomTag.Room;
						if (room != null)
						{
							Parameter parameter = room.GetParameter(BuiltInParameter.ROOM_NAME);
							string text = parameter.AsString();
							int num2 = text.IndexOf(strSearch);
							string text2 = text.Substring(0, num2);
							string text3 = text.Substring(num2 + strSearch.Length);
							text = string.Concat(new string[]
							{
								text2,
								strPrefix,
								strSearch,
								strSuffix,
								text3
							});
							parameter.Set(text);
							num++;
						}
					}
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				num = 0;
				transaction.RollBack();
			}
			this.ClearPosRectangle(false);
			return num;
		}

		private Result PickSearchReplaceText(RoomNameSearchReplaceForm dlg)
		{
			dlg.Hide();
			FilterRoomTag filterRoomTag = new FilterRoomTag();
			Reference reference = null;
			try
			{
				reference = this.m_uiDoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, filterRoomTag, "请拾取一个房间标记");
			}
			catch (Exception)
			{
				dlg.Show(CmdRoomNameSearchReplace._hWndRevit);
				this.ResetSeletType(dlg);
				return Autodesk.Revit.UI.Result.Failed;
			}
			RoomTag roomTag = this.m_doc.GetElement(reference) as RoomTag;
			if (roomTag == null)
			{
				dlg.Show(CmdRoomNameSearchReplace._hWndRevit);
				this.ResetSeletType(dlg);
				return Autodesk.Revit.UI.Result.Failed;
			}
			Room room = roomTag.Room;
			if (room == null)
			{
				dlg.Show(CmdRoomNameSearchReplace._hWndRevit);
				this.ResetSeletType(dlg);
				return Autodesk.Revit.UI.Result.Failed;
			}
			string text = room.get_Parameter(BuiltInParameter.ROOM_NAME).AsString();
			RoomNameSearchReplaceForm.SelecionType seletType = dlg.SeletType;
			if (seletType != RoomNameSearchReplaceForm.SelecionType.ePickSearch)
			{
				if (seletType == RoomNameSearchReplaceForm.SelecionType.ePickReplace)
				{
					dlg.cmbReplace.Text = text;
					dlg.cmbReplace.Items.Add(text);
				}
			}
			else
			{
				dlg.cmbSearch.Text = text;
				dlg.cmbSearch.Items.Add(text);
			}
			this.ResetSeletType(dlg);
			dlg.Show(CmdRoomNameSearchReplace._hWndRevit);
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		private void ResetSeletType(RoomNameSearchReplaceForm dlg)
		{
			if (dlg.radBoxSel.Checked)
			{
				dlg.SeletType = RoomNameSearchReplaceForm.SelecionType.eBoxSel;
				return;
			}
			if (dlg.radCurView.Checked)
			{
				dlg.SeletType = RoomNameSearchReplaceForm.SelecionType.eCurView;
				return;
			}
			if (dlg.radAllView.Checked)
			{
				dlg.SeletType = RoomNameSearchReplaceForm.SelecionType.eAllView;
			}
		}

		private void CreatePosLineStyle()
		{
            this.m_lineStyle = LineTypeTool.CreateLineType(this.m_doc, "红色定位线", new Autodesk.Revit.DB.Color(byte.MaxValue, 0, 0), 1, (GraphicsStyleType)1);
		}

		public void RefreshSearchData()
		{
			this.m_lstRoomTag.Clear();
			this.ClearPosRectangle(false);
		}

		private void PositionTextRoomTag()
		{
			this.ClearPosRectangle(false);
			Transaction transaction = new Transaction(this.m_doc, "Draw Tag BoundingBox");
			try
			{
				transaction.Start();
				foreach (RoomTag roomTag in this.m_lstRoomTag)
				{
					if (roomTag != null)
					{
						BoundingBoxXYZ boundingBoxXYZ = roomTag.get_BoundingBox(roomTag.View);
						XYZ min = boundingBoxXYZ.Min;
						XYZ max = boundingBoxXYZ.Max;
						XYZ xyz = new XYZ(min.X, max.Y, min.Z);
						XYZ xyz2 = new XYZ(max.X, min.Y, min.Z);
						Line line = Line.CreateBound(min, xyz);
						Line line2 = Line.CreateBound(xyz, max);
						Line line3 = Line.CreateBound(max, xyz2);
						Line line4 = Line.CreateBound(min, xyz2);
						DetailCurve detailCurve = this.m_doc.Create.NewDetailCurve(this.m_doc.ActiveView, line);
						detailCurve.LineStyle = this.m_lineStyle;
						this.m_lstPosLineId.Add(detailCurve.Id);
						DetailCurve detailCurve2 = this.m_doc.Create.NewDetailCurve(this.m_doc.ActiveView, line2);
						detailCurve2.LineStyle = this.m_lineStyle;
						this.m_lstPosLineId.Add(detailCurve2.Id);
						DetailCurve detailCurve3 = this.m_doc.Create.NewDetailCurve(this.m_doc.ActiveView, line3);
						detailCurve3.LineStyle = this.m_lineStyle;
						this.m_lstPosLineId.Add(detailCurve3.Id);
						DetailCurve detailCurve4 = this.m_doc.Create.NewDetailCurve(this.m_doc.ActiveView, line4);
						detailCurve4.LineStyle = this.m_lineStyle;
						this.m_lstPosLineId.Add(detailCurve4.Id);
					}
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		public void ClearPosRectangle(bool bDelLineStyle = false)
		{
			if (this.m_lstPosLineId.Count <= 0)
			{
				return;
			}
			Transaction transaction = new Transaction(this.m_doc, "Delete PositionRectangle");
			try
			{
				transaction.Start();
				this.m_doc.Delete(this.m_lstPosLineId);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
			this.m_lstPosLineId.Clear();
			if (bDelLineStyle)
			{
				LineTypeTool.DeleteLineType(this.m_doc, "红色定位线");
			}
		}

		private UIDocument m_uiDoc;

		private Autodesk.Revit.DB.Document m_doc;

		private GraphicsStyle m_lineStyle;

		private List<RoomTag> m_lstRoomTag = new List<RoomTag>();

		private List<ElementId> m_lstPosLineId = new List<ElementId>();
	}
}
